﻿using Angle.Krill.Utils;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Windows.Forms;

namespace Angle.Krill
{
    public partial class SearchFiles : DummyWindow
    {
        private AntdUI.IContextMenuStripItem[] rightMenu = null;
        private string volumeName = string.Empty;
        private string searchText = string.Empty;
        private bool ignoreCase = false;
        private bool matchWhole = false;
        private List<FSInfo> fSInfos = new List<FSInfo>();
        private int totalCount = 0;
        private int pageSize = 50;
        private int current = 1;

        public SearchFiles(string volumeName, string searchText, bool ignoreCase, bool matchWhole) : this()
        {
            this.volumeName = volumeName;
            this.searchText = searchText;
            this.ignoreCase = ignoreCase;
            this.matchWhole = matchWhole;
        }

        public SearchFiles()
        {
            InitializeComponent();
            this.KeyPreview = true;
        }

        private void SearchFiles_Load(object sender, EventArgs e)
        {
            this.Icon = ImageHelper.ConvertToIcon(ImageHelper.FileIcon);

            this.InitializeRightMenu();
            this.InitializeTable();

            this.BindData(this.volumeName, this.searchText, this.ignoreCase, this.matchWhole);
        }

        private void pFiles_ValueChanged(int current, int total, int pageSize, int pageTotal)
        {
            this.current = current;
            this.pageSize = pageSize;

            this.BindData(this.volumeName, this.searchText, this.ignoreCase, this.matchWhole, true);
        }
        public void BindData(string volumeName, string searchText, bool ignoreCase, bool matchWhole, bool isPager = false)
        {
            this.volumeName = volumeName;
            this.searchText = searchText;
            this.ignoreCase = ignoreCase;
            this.matchWhole = matchWhole;

            if (!isPager)
            {
                this.fSInfos = MFTScannerHelper.Instance.EnumerateFiles(this.volumeName, this.searchText, this.ignoreCase, this.matchWhole).ToList();
            }

            if (this.fSInfos.Count == 0)
            {
                this.pFiles.Visible = false;
            }
            else
            {
                this.pFiles.Visible = true;
            }

            var items = this.fSInfos.Skip(this.pageSize * (this.current - 1)).Take(this.pageSize).ToList();

            this.totalCount = this.fSInfos.Count;
            this.pFiles.Total = this.totalCount;
            this.pFiles.Current = this.current > this.pFiles.PageTotal ? 1 : this.current;

            this.tableFiles.DataSource = this.ConvertToFileList(items);
        }

        private void InitializeRightMenu()
        {
            this.rightMenu = new AntdUI.IContextMenuStripItem[]
            {
                new AntdUI.ContextMenuStripItem("打开"){
                    Tag="OpenFile"
                },
                new AntdUI.ContextMenuStripItem("刷新"){
                    Tag="Refresh"
                },
                new AntdUI.ContextMenuStripItemDivider(),
                new AntdUI.ContextMenuStripItem("剪切","Ctrl+X"){
                    Tag="Cut"
                },
                new AntdUI.ContextMenuStripItem("复制","Ctrl+C"){
                    Tag="Copy"
                },
                new AntdUI.ContextMenuStripItemDivider(),
                new AntdUI.ContextMenuStripItem("在文件资源管理器打开"){
                    Icon = ImageHelper.OpenFolderIcon,
                    Tag="OpenToFileExplorer"
                }
            };
        }

        private void InitializeTable()
        {
            this.tableFiles.CtrlCKey = () =>
            {
                this.CopyFile();
            };
            this.tableFiles.Columns = new AntdUI.Column[] {
                new AntdUI.ColumnCheck("Check"){ Fixed=true},
                new AntdUI.Column("Name","文件名"){
                    Fixed=true,
                    Width="150",
                    LineBreak=true
                },
                new AntdUI.Column("FileSize","大小",AntdUI.ColumnAlign.Right),
                new AntdUI.Column("PhysicalPath","路径",AntdUI.ColumnAlign.Left),
                new AntdUI.Column("LastModifyDatetime","最近一次修改时间",AntdUI.ColumnAlign.Center){
                    Width="120",
                    LineBreak=true
                },
                new AntdUI.Column("Remark","备注",AntdUI.ColumnAlign.Left)
            };
        }

        private void tableFiles_CellClick(object sender, MouseEventArgs args, object record, int rowIndex, int columnIndex, Rectangle rect)
        {
            if (args.Button == MouseButtons.Right)
            {
                AntdUI.ContextMenuStrip.open(this.tableFiles, it =>
                {
                    if (it.Tag?.ToString() == "OpenToFileExplorer")
                    {
                        this.OpenToFileExplorer(record as FileList);
                    }
                    else if (it.Tag?.ToString() == "OpenFile")
                    {
                        this.OpenFile(record as FileList);
                    }
                    else if (it.Tag?.ToString() == "Refresh")
                    {
                        this.BindData(this.volumeName, this.searchText, this.ignoreCase, this.matchWhole);
                    }
                    else if (it.Tag?.ToString() == "Cut")
                    {
                        this.CutFile();
                    }
                    else if (it.Tag?.ToString() == "Copy")
                    {
                        this.CopyFile();
                    }
                }, this.rightMenu);
            }
        }

        private void tableFiles_KeyDown(object sender, KeyEventArgs e)
        {
        }

        private void Files_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.Modifiers == Keys.Control && e.KeyCode == Keys.X)
            {
                this.CutFile();
            }
            else if (e.Modifiers == Keys.Control && e.KeyCode == Keys.C)
            {
                this.CopyFile();
            }
            e.Handled = true;
        }

        private void CutFile()
        {
            var lst = this.tableFiles.GetSelectRow<FileList>();
            OptFile optFile = new OptFile
            {
                Files = lst,
                Opt = "cut"
            };
            Clipboard.SetText(CodeHelper.Base64Encrypt(JsonConvert.SerializeObject(optFile)));
        }

        private void CopyFile()
        {
            var lst = this.tableFiles.GetSelectRow<FileList>();
            OptFile optFile = new OptFile
            {
                Files = lst,
                Opt = "copy"
            };
            Clipboard.SetText(CodeHelper.Base64Encrypt(JsonConvert.SerializeObject(optFile)));
        }

        private void tableFiles_CellDoubleClick(object sender, MouseEventArgs args, object record, int rowIndex, int columnIndex, Rectangle rect)
        {
            this.OpenFile(record as FileList);
        }
        /// <summary>
        /// 打开文件
        /// </summary>
        /// <param name="fileInfo"></param>
        private void OpenFile(FileList fileInfo)
        {
            if (string.IsNullOrEmpty(fileInfo?.PhysicalPath))
            {
                return;
            }

            FileHelper.ProcessStart(fileInfo.PhysicalPath, fileLockCallback);
        }

        private void fileLockCallback()
        {
            AntdUI.Message.info(this.ParentForm, "文件已被占用!", Font);
        }

        private void OpenToFileExplorer(FileList fileInfo)
        {
            if (string.IsNullOrEmpty(fileInfo?.PhysicalPath))
            {
                return;
            }

            FileHelper.ProcessStart(new ProcessStartInfo
            {
                Arguments = Path.GetDirectoryName(fileInfo.PhysicalPath),
                FileName = "explorer.exe"
            });
        }

        private List<FileList> ConvertToFileList(List<FSInfo> files)
        {
            //var lstFile = AutoMapperHelper.AutoMapperToList<FSInfo, FileList>(files);
            List<FileList> lstFile = new List<FileList>();
            foreach (var item in files)
            {
                FileInfo fInfo = null;
                string remark = string.Empty;
                try
                {
                    fInfo = new FileInfo(item.Path);
                }
                catch (Exception ex)
                {
                    remark = ex.Message;
                }

                var f = new FileList
                {
                    PhysicalPath = item.Path,
                    Name = item.Name,
                    NameWithoutExtend = Path.GetFileNameWithoutExtension(item.Name),
                    LastModifyDatetime = fInfo?.LastWriteTime,
                    Size = fInfo?.Length,
                    Remark = remark
                };

                lstFile.Add(f);
            }
            return lstFile;
        }
    }
}
